package com.tools.developer.root;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
//Root后   
// 开机启动项管理    http://su1216.iteye.com/blog/1675800
public class SuExec {

	private DataOutputStream mDataOutputStream = null;
	private DataInputStream mDataInputStream = null;
	private DataInputStream mDataErrStream = null;
	private Process mProcess = null;
	private static SuExec mInstance;
	private boolean bRet = false;
	private Thread mThreadGetSu = null;

	public synchronized static SuExec getInstance() {
		if (mInstance == null) {
			mInstance = new SuExec();
		}
		return mInstance;
	}

	// 判断手机是否被ROOT
	public boolean isMobileRoot() {

		String rootpath = xGetCmdPath("su");
		return (rootpath != null);
	}

	Runnable mRunGetSu = new Runnable() {
		@Override
		public void run() {
			enterRootByMethod();
		}

	};

	public boolean enterRootByMethod() {
		if (mProcess == null || mDataOutputStream == null) {
			boolean bRootOk = false;
			Process process = null;
			DataOutputStream dataOutputStream = null;
			DataInputStream dataInputStream = null;
			DataInputStream dataErrStream = null;
			try {
				process = Runtime.getRuntime().exec("su");
				dataOutputStream = new DataOutputStream(
						process.getOutputStream());
				dataInputStream = new DataInputStream(process.getInputStream());
				dataErrStream = new DataInputStream(process.getErrorStream());
				for (int i = 0; i < 5; i++) {
					if (isRootOk(dataOutputStream, dataInputStream,
							dataErrStream)) {
						bRootOk = true;
						break;
					}
					Thread.sleep(100);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (process == null || dataInputStream == null
					|| dataOutputStream == null || !bRootOk) {
				if (dataInputStream != null) {
					try {
						dataInputStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
					dataInputStream = null;
				}
				if (dataOutputStream != null) {
					try {
						dataOutputStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
					dataOutputStream = null;
				}
				if (process != null) {
					process.destroy();
					process = null;
				}
				bRet = false;
			} else {
				bRet = true;
			}

			synchronized (SuExec.this) {
				SuExec.this.mProcess = process;
				SuExec.this.mDataInputStream = dataInputStream;
				SuExec.this.mDataOutputStream = dataOutputStream;
				SuExec.this.mDataErrStream = dataErrStream;
				SuExec.this.mThreadGetSu = null;
			}
		}
		return bRet;
	}

	public synchronized void enterRootByRunnable() {
		if (mThreadGetSu == null) {
			mThreadGetSu = new Thread(mRunGetSu);
			mThreadGetSu.start();
		}
	}

	public synchronized boolean execCmd(String strCmd) // 需要回车符号
	{

		boolean result = false;
		if (mDataOutputStream != null) {
			try {
				mDataOutputStream.writeBytes(strCmd);
				mDataOutputStream.flush();
				result = true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	private static boolean isRootOk(DataOutputStream output,
			DataInputStream input, final DataInputStream errInput) {
		if (output != null) {
			try {
				output.writeBytes("id\n");
				output.flush();
				String a = input.readLine();
				if (a.contains("root") || a.contains("uid=0")) {
					return true;
				}
				new Thread() {
					@Override
					public void run() {
						try {
							errInput.read();
						} catch (IOException e) {
							e.printStackTrace();
						}
					};
				}.start();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return false;
	}

	public void leaveRoot() {

		if (mDataOutputStream != null) {
			try {
				mDataOutputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			mDataOutputStream = null;
		}
		if (mDataInputStream != null) {
			try {
				mDataInputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			mDataInputStream = null;
		}
		if (mProcess != null) {
			mProcess.destroy();
			mProcess = null;
		}
	}

	public boolean checkRoot() {

		return (mProcess != null) && (mDataOutputStream != null);
	}

	private static final String[] bin_dirs = { "/system/sbin/",
			"/system/xbin/", "/system/bin/" };

	private String xGetCmdPath(String cmd) {

		if (cmd.indexOf('/') != -1) {
			return cmd;
		}
		for (int i = 0; i < bin_dirs.length; i++) {
			try {
				String path = bin_dirs[i] + cmd;
				if (new File(path).exists()) {
					return path;
				}
			} catch (Exception e) {
				e.printStackTrace();
				continue;
			}
		}
		return null;
	}

}
